use {
    repository::model::{
        dapp_block_scan_progress::{self, DAppBlockScanProgress},
        dapp_contract::DAppContract,
        dapp_wallet::DAppWallet,
    },
    sqlx::{MySql, Pool},
    std::str::FromStr,
    tracing::{error, info, warn},
    tron::{base, biz},
};

const CHAIN: &str = "TRON";

pub async fn job(env: &str, pool: &Pool<MySql>) -> anyhow::Result<()> {
    let mut interval_timer = tokio::time::interval(std::time::Duration::from_secs(60));
    let client = base::client::build_client(env);

    loop {
        interval_timer.tick().await;
        let dapp_block_scan_progress_ret =
            DAppBlockScanProgress::select_by_chain(CHAIN, &pool).await;
        if let Err(e) = &dapp_block_scan_progress_ret {
            error!("select block scan progress error: {e}");
        }
        let dapp_block_scan_progress = dapp_block_scan_progress_ret.unwrap();
        let current_block_number = dapp_block_scan_progress.number;
        let scan_progress_id = dapp_block_scan_progress.id.unwrap();

        let contract_entites_ret = DAppContract::select_all(CHAIN, &pool).await;
        if let Err(e) = contract_entites_ret {
            error!("select contract error: {e}");
            continue;
        }
        let contract_entites = contract_entites_ret.unwrap();
        let mut contracts = Vec::new();
        for entity in contract_entites {
            let mint_pk_str = entity.addr;
            contracts.push(mint_pk_str);
        }

        let account_entities_ret = DAppWallet::select_all(&pool).await;
        if let Err(e) = account_entities_ret {
            error!("select account error: {e}");
            continue;
        }
        let account_entities = account_entities_ret.unwrap();
        let mut accounts = Vec::new();
        for entity in account_entities {
            let account_pk_str = entity.tron_pk;
            accounts.push(account_pk_str);
        }
        
        if contracts.len()==0 || accounts.len()==0 {
            warn!("no contract or account found");
            continue;
        }

        let listen_ret = biz::listen::listen_token(
            &client,
            &pool,
            &contracts,
            &accounts,
            current_block_number,
            scan_progress_id,
        )
        .await;
        if let Err(e) = listen_ret {
            error!("listen token error: {e}");
            continue;
        }
    }
}
